package com.xyz.rok.tools.service.impl;

import com.xyz.rok.tools.model.UnionMember;
import com.xyz.rok.tools.model.dto.StatDto;
import com.xyz.rok.tools.model.request.DkpStatRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import com.xyz.rok.tools.model.PlayerStat;
import com.xyz.rok.tools.mapper.PlayerStatMapper;
import com.xyz.rok.tools.service.PlayerStatService;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class PlayerStatServiceImpl implements PlayerStatService {

    @Resource
    private PlayerStatMapper playerStatMapper;

    @Override
    public int deleteByPrimaryKey(Long id) {
        return playerStatMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(PlayerStat record) {
        return playerStatMapper.insert(record);
    }

    @Override
    public int insertSelective(PlayerStat record) {
        return playerStatMapper.insertSelective(record);
    }

    @Override
    public PlayerStat selectByPrimaryKey(Long id) {
        return playerStatMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(PlayerStat record) {
        return playerStatMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(PlayerStat record) {
        return playerStatMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<String> getFinishedNames(Integer serverId) {
        Integer day = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        return playerStatMapper.getFinishedNames(serverId, day);
    }

    @Override
    public void insertOrUpdate(DkpStatRequest dkpStatRequest) {
        Integer day = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        PlayerStat playerStatDb = playerStatMapper.selectByServerIdGameIdDay(dkpStatRequest.getServerId(), dkpStatRequest.getGameId(), day);
        PlayerStat playerStat = new PlayerStat();
        BeanUtils.copyProperties(dkpStatRequest, playerStat);
        if (playerStatDb == null) {
            playerStat.setCreateTime(new Date());
            playerStat.setDay(day);
            playerStatMapper.insertSelective(playerStat);
        } else {
            playerStat.setUpdateTime(new Date());
            playerStat.setDay(day);
            playerStatMapper.updateByPrimaryKeySelective(playerStat);
        }
    }

    @Override
    public List<StatDto> getStatDate(Integer serverId, Integer day, String orderBy) {
        return playerStatMapper.selectStatDto(serverId,day,orderBy);
    }

    @Override
    public List<Integer> getHasDataDay(Integer serverId) {
        return playerStatMapper.getHasDataDay(serverId);
    }

    @Override
    public List<StatDto> getStatCompare(Integer serverId, Integer beginDate, Integer endDate, String orderBy) {
        List<StatDto> listBegin = playerStatMapper.selectStatDtoByDay(serverId, beginDate, orderBy);
        List<StatDto> listEnd = playerStatMapper.selectStatDtoByDay(serverId, endDate, orderBy);
        List<StatDto> listResult = new ArrayList<>();
        Set<Long> gameIdSet = new HashSet<>();
        Map<Long, StatDto> mapBegin = new HashMap((int) (listBegin.size() / 0.75 + 1));
        Map<Long, StatDto> mapEnd = new HashMap((int) (listEnd.size() / 0.75 + 1));
        for (StatDto memberStatDto : listBegin) {
            gameIdSet.add(memberStatDto.getGameId());
            mapBegin.put(memberStatDto.getGameId(), memberStatDto);
        }
        for (StatDto memberStatDto : listEnd) {
            gameIdSet.add(memberStatDto.getGameId());
            mapEnd.put(memberStatDto.getGameId(), memberStatDto);
        }
        StatDto memberStatDto = null;
        for (Long gameId : gameIdSet) {
            memberStatDto = new StatDto();
            memberStatDto.setGameId(gameId);
            if (mapBegin.get(gameId) == null || mapEnd.get(gameId) == null) {
                memberStatDto.setNickname(mapBegin.get(gameId) == null ? (mapEnd.get(gameId) == null ? "未知" : mapEnd.get(gameId).getNickname()) : mapBegin.get(gameId).getNickname());
                memberStatDto.setBeginValue(mapBegin.get(gameId) == null ? 0 : mapBegin.get(gameId).getValue());
                memberStatDto.setEndValue(mapEnd.get(gameId) == null ? 0 : mapEnd.get(gameId).getValue());
                memberStatDto.setValue(0);
            } else {
                memberStatDto.setNickname(mapEnd.get(gameId).getNickname());
                memberStatDto.setBeginValue(mapBegin.get(gameId).getValue());
                memberStatDto.setEndValue(mapEnd.get(gameId).getValue());
                memberStatDto.setValue(memberStatDto.getEndValue() - memberStatDto.getBeginValue());
            }
            listResult.add(memberStatDto);
        }
        Collections.sort(listResult, (o1, o2) -> {
            int v1 = o1.getValue();
            int v2 = o2.getValue();
            return v2 - v1;
        });
        return listResult;
    }

    @Override
    public List<StatDto> selectStatDownloadByDay(Integer serverId, Integer day) {
        return playerStatMapper.selectStatDownloadByDay(serverId, day);
    }

    @Override
    public List<StatDto> getDKPCompare(Integer serverId, Integer beginDate, Integer endDate, Integer t4Kill, Integer t5Kill, Integer death) {
        List<StatDto> listBegin = playerStatMapper.selectDKPByDay(serverId, beginDate, t4Kill, t5Kill, death);
        List<StatDto> listEnd = playerStatMapper.selectDKPByDay(serverId, endDate, t4Kill, t5Kill, death);
        List<StatDto> listResult = new ArrayList<>();
        Set<Long> gameIdSet = new HashSet<>();
        Map<Long, StatDto> mapBegin = new HashMap((int) (listBegin.size() / 0.75 + 1));
        Map<Long, StatDto> mapEnd = new HashMap((int) (listEnd.size() / 0.75 + 1));
        for (StatDto memberStatDto : listBegin) {
            gameIdSet.add(memberStatDto.getGameId());
            mapBegin.put(memberStatDto.getGameId(), memberStatDto);
        }
        for (StatDto memberStatDto : listEnd) {
            gameIdSet.add(memberStatDto.getGameId());
            mapEnd.put(memberStatDto.getGameId(), memberStatDto);
        }

        StatDto memberStatDto = null;
        for (Long gameId : gameIdSet) {
            memberStatDto = new StatDto();
            memberStatDto.setGameId(gameId);
            if (mapBegin.get(gameId) == null || mapEnd.get(gameId) == null) {
                memberStatDto.setNickname(mapBegin.get(gameId) == null ? (mapEnd.get(gameId) == null ? "未知" : mapEnd.get(gameId).getNickname()) : mapBegin.get(gameId).getNickname());
                memberStatDto.setBeginValue(mapBegin.get(gameId) == null ? 0 : mapBegin.get(gameId).getValue());
                memberStatDto.setEndValue(mapEnd.get(gameId) == null ? 0 : mapEnd.get(gameId).getValue());
                memberStatDto.setValue(0);
            } else {
                memberStatDto.setNickname(mapEnd.get(gameId).getNickname());
                memberStatDto.setBeginValue(mapBegin.get(gameId).getValue());
                memberStatDto.setEndValue(mapEnd.get(gameId).getValue());
                memberStatDto.setValue(memberStatDto.getEndValue() - memberStatDto.getBeginValue());
            }
            listResult.add(memberStatDto);
        }
        Collections.sort(listResult, (o1, o2) -> {
            int v1 = o1.getValue();
            int v2 = o2.getValue();
            return v2 - v1;
        });
        return listResult;
    }

}
